﻿using System;
using System.Windows;
using System.Windows.Interop;

using Microsoft.Windows.UserControls.Core.Win32;

namespace Microsoft.Windows.UserControls.Core.Behaviors
{
    public static class WindowEx
    {
        public static readonly DependencyProperty ControlBoxVisibleProperty = DependencyProperty.RegisterAttached("ControlBoxVisible", typeof(Boolean), typeof(WindowEx), new UIPropertyMetadata(true, ControlBoxVisiblePropertyChanged));
    
        [AttachedPropertyBrowsableForType(typeof (Window))]
        public static Boolean GetControlBoxVisible(DependencyObject obj)
        {
            return (Boolean)obj.GetValue(ControlBoxVisibleProperty);
        }

        [AttachedPropertyBrowsableForType(typeof (Window))]
        public static void SetControlBoxVisible(DependencyObject obj, object value)
        {
            obj.SetValue(ControlBoxVisibleProperty, value);
        }

        static void ControlBoxVisiblePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            var window = sender as Window;
            if (window == null)
                return;
            
            if (window.IsLoaded) if ((Boolean)args.NewValue)
                SetWindowControlBoxVisible(window);
            else
                SetWindowControlBoxHidden(window);
            else if ((Boolean)args.NewValue)
                window.Loaded += OnWindowLoadedSetWindowControlBoxVisible;
            else
                window.Loaded += OnWindowLoadedSetWindowControlBoxHidden;
        }

        static void OnWindowLoadedSetWindowControlBoxHidden(object sender, RoutedEventArgs e)
        {
            var window = sender as Window;
            if (window == null)
                return;
            SetWindowControlBoxHidden(window);
            window.Loaded -= OnWindowLoadedSetWindowControlBoxHidden;
        }
    
        static void OnWindowLoadedSetWindowControlBoxVisible(object sender, RoutedEventArgs e)
        {
            var window = sender as Window;
            if (window == null)
                return;
            SetWindowControlBoxVisible(window);
            window.Loaded -= OnWindowLoadedSetWindowControlBoxVisible;
        }
    
        static void SetWindowControlBoxHidden(Window window)
        {
            var hwnd = new WindowInteropHelper(window).Handle;
            NativeMethods.SetWindowLongPtr(hwnd, NativeMethods.GWL_STYLE, NativeMethods.GetWindowLongPtr(hwnd, NativeMethods.GWL_STYLE) & ~NativeMethods.WS_SYSMENU);
        }
        
        static void SetWindowControlBoxVisible(Window window)
        {
            var hwnd = new WindowInteropHelper(window).Handle;
            NativeMethods.SetWindowLongPtr(hwnd, NativeMethods.GWL_STYLE, NativeMethods.GetWindowLongPtr(hwnd, NativeMethods.GWL_STYLE) | NativeMethods.WS_SYSMENU);
        }
        
    }
}